import { Card, Descriptions, Progress, Space } from "antd";
import { useEffect, useState } from "react";
import { getSftpApi, getToken } from "./utils/client";

export interface SysInfoPanelProps {
    curClientId: string
}

function SysInfoPanel(props: SysInfoPanelProps) {

    const twoColors = { '0%': 'green', '100%': 'red' };

    const [load1, setLoad1] = useState("");
    const [load5, setLoad5] = useState("");
    const [load15, setLoad15] = useState("");

    const setCpuUser = useState(0)[1];
    const setCpuNice = useState(0)[1];
    const setCpuSystem = useState(0)[1];
    const setCpuIdle = useState(0)[1];
    const setCpuIowait = useState(0)[1];
    const setCpuIrq = useState(0)[1];
    const setCpuSoftirq = useState(0)[1];

    const [cpuUserDiff, setCpuUserDiff] = useState(0);
    const [cpuNiceDiff, setCpuNiceDiff] = useState(0);
    const [cpuSystemDiff, setCpuSystemDiff] = useState(0);
    const [cpuIdleDiff, setCpuIdleDiff] = useState(0);
    const [cpuIowaitDiff, setCpuIowaitDiff] = useState(0);
    const [cpuIrqDiff, setCpuIrqRatioDiff] = useState(0);
    const [cpuSoftirqDiff, setCpuSoftirqDiff] = useState(0);

    const [memTotal, setMemTotal] = useState(0);
    const [memFree, setMemFree] = useState(0);
    const [memAvail, setMemAvail] = useState(0);

    const calcCpuTotalDiff = () => {
        const total = cpuUserDiff + cpuNiceDiff + cpuSystemDiff + cpuIdleDiff + cpuIowaitDiff + cpuIrqDiff + cpuSoftirqDiff;
        if (total < 0.00001) {
            return 1;
        }
        return total;
    };

    const parseUpload = async () => {
        const api = getSftpApi();
        const res = await api.sftpReadTextPost({
            sftpReadTextPostRequest: {
                id: props.curClientId,
                token: getToken(),
                path: "/proc/loadavg",
            },
        });
        const partList = res.split(/\s+/);
        if (partList.length > 3) {
            setLoad1(partList[0]);
            setLoad5(partList[1]);
            setLoad15(partList[2]);
        }
    };

    const parseCpu = async () => {
        const api = getSftpApi();
        const res = await api.sftpReadTextPost({
            sftpReadTextPostRequest: {
                id: props.curClientId,
                token: getToken(),
                path: "/proc/stat",
            },
        });
        for (const line of res.split("\n")) {
            if (line.startsWith("cpu ")) {
                const parts = line.split(/\s+/);
                if (parts.length >= 8) {
                    setCpuUser(oldValue => {
                        const newValue = parseInt(parts[1]);
                        setCpuUserDiff(newValue - oldValue);
                        return newValue;
                    });
                    setCpuNice(oldValue => {
                        const newValue = parseInt(parts[2]);
                        setCpuNiceDiff(newValue - oldValue);
                        return newValue;
                    });
                    setCpuSystem(oldValue => {
                        const newValue = parseInt(parts[3]);
                        setCpuSystemDiff(newValue - oldValue);
                        return newValue;
                    });
                    setCpuIdle(oldValue => {
                        const newValue = parseInt(parts[4]);
                        setCpuIdleDiff(newValue - oldValue);
                        return newValue;
                    });
                    setCpuIowait(oldValue => {
                        const newValue = parseInt(parts[5]);
                        setCpuIowaitDiff(newValue - oldValue);
                        return newValue;
                    });
                    setCpuIrq(oldValue => {
                        const newValue = parseInt(parts[6]);
                        setCpuIrqRatioDiff(newValue - oldValue);
                        return newValue;
                    });
                    setCpuSoftirq(oldValue => {
                        const newValue = parseInt(parts[7]);
                        setCpuSoftirqDiff(newValue - oldValue);
                        return newValue;
                    });
                }
            }
        }
    };

    const parseMem = async () => {
        const api = getSftpApi();
        const res = await api.sftpReadTextPost({
            sftpReadTextPostRequest: {
                id: props.curClientId,
                token: getToken(),
                path: "/proc/meminfo",
            },
        });
        for (const line of res.split("\n")) {
            const parts = line.split(":").map(item => item.trim().replace(/\s+/, "").replace("kB", "000"));
            if (parts.length == 2) {
                if (parts[0] == "MemTotal") {
                    setMemTotal(parseInt(parts[1]));
                } else if (parts[0] == "MemFree") {
                    setMemFree(parseInt(parts[1]));
                } else if (parts[0] == "MemAvailable") {
                    setMemAvail(parseInt(parts[1]));
                }
            }
        }
    };
    const loadSysInfo = async () => {
        parseUpload();
        parseCpu();
        parseMem();
    };

    useEffect(() => {
        loadSysInfo();
        const h = setInterval(() => {
            loadSysInfo();
        }, 1000);

        return () => clearInterval(h);
    }, [props.curClientId]);

    return (
        <Card title="系统信息" style={{ height: "calc(50vh - 50px)", overflowY: "hidden" }} bodyStyle={{ height: "calc(50vh - 110px)", overflowY: "auto", padding: "0px 10px" }}>
            <Descriptions column={1} bordered={true} labelStyle={{ width: "60px" }}>
                <Descriptions.Item label="负载">
                    <Space>
                        {load1}
                        {load5}
                        {load15}
                    </Space>
                </Descriptions.Item>
                <Descriptions.Item label="cpu使用(user)">
                    <Progress percent={Math.round(cpuUserDiff * 100 / calcCpuTotalDiff())} strokeColor={twoColors} type="dashboard" width={60} />
                </Descriptions.Item>
                <Descriptions.Item label="cpu使用(ni)">
                    <Progress percent={Math.round(cpuNiceDiff * 100 / calcCpuTotalDiff())} strokeColor={twoColors} type="dashboard" width={60} />
                </Descriptions.Item>
                <Descriptions.Item label="cpu使用(sys)">
                    <Progress percent={Math.round(cpuSystemDiff * 100 / calcCpuTotalDiff())} strokeColor={twoColors} type="dashboard" width={60} />
                </Descriptions.Item>
                <Descriptions.Item label="cpu使用(idle)">
                    <Progress percent={Math.round(cpuIdleDiff * 100 / calcCpuTotalDiff())} strokeColor={twoColors} type="dashboard" width={60} />
                </Descriptions.Item>
                <Descriptions.Item label="cpu使用(iowait)">
                    <Progress percent={Math.round(cpuIowaitDiff * 100 / calcCpuTotalDiff())} strokeColor={twoColors} type="dashboard" width={60} />
                </Descriptions.Item>
                {memTotal > 0 && (
                    <>
                        <Descriptions.Item label="内存使用">
                            <Progress percent={Math.round((memTotal - memFree) * 100 / memTotal)} strokeColor={twoColors} type="dashboard" width={60} />
                        </Descriptions.Item>
                        <Descriptions.Item label="可用内存">
                            <Progress percent={Math.round(memAvail * 100 / memTotal)} strokeColor={twoColors} type="dashboard" width={60} />
                        </Descriptions.Item>
                    </>
                )}
            </Descriptions>
        </Card>
    );

}

export default SysInfoPanel;